#ifndef N2GEOMETRY_H_2006_11_22
#define N2GEOMETRY_H_2006_11_22

#include "N0Lib.h"

typedef uint32   N2Coord;
typedef uint32   N2Length;

class N2Point {
public:
    N2Coord x, y;

    N2Point() : x(0), y(0) { };
    N2Point(N2Coord _x, N2Coord _y) : x(_x), y(_y) { };
    N2Point(const N2Point& point) : x(point.x), y(point.y) { };
};

class N2Size {
public:
    uint32 width, height;

    N2Size() : width(0), height(0) { };
    N2Size(const N2Size &size) : width(size.width), height(size.height) { };
    N2Size(uint32 w, uint32 h) : width(w), height(h) { };

    void get(uint32 &w, uint32 &h);

    void change(int32 dw, int32 dh) { width += dw; height += dh; };

    bool inRectFromSize(N2Coord x, N2Coord y) const { return x<width && y<height; };
};

class N2Rect {
public:
    N2Coord left, top;
    N2Coord right, bottom;

    N2Rect() : left(0), top(0), right(0), bottom(0) { };
    N2Rect(N2Coord l, N2Coord t, N2Coord r, N2Coord b) : left(l), top(t), 
                                                         right(r), bottom(b) { };
    N2Rect(const N2Rect& rect) : left(rect.left), top(rect.top), 
                                 right(rect.right), bottom(rect.bottom) { };

    N2Rect(const N2Size& size) : left(0), top(0), 
                                 right(size.width - 1), bottom(size.height - 1) { };

#ifdef WINDOWS
    N2Rect(const RECT& rect) : left(rect.left), top(rect.top), 
                                 right(rect.right), bottom(rect.bottom) { };
#endif

    bool isEmpty() const { return (right<left) || (top>bottom); };

    uint32 width() const { return right - left + 1; };
    uint32 height() const { return bottom - top + 1; };

    N2Size size() const { return N2Size(width(), height()); };

    void expandLeft(N2Coord l) { if(left>l) left = l; };
    void expandTop(N2Coord t)  { if(top>t) top = t; };
    void expandRight(N2Coord r)  { if(right < r) right = r; };
    void expandBottom(N2Coord b) { if(bottom < b) bottom = b; };

    void expand(const N2Rect &rect) 
    {
        if(left>rect.left) left = rect.left;
        if(right<rect.right) right = rect.right;
        if(top>rect.top) top = rect.top;
        if(bottom<rect.bottom) bottom = rect.bottom;
    };

    void trimRight(N2Coord &r) { if(r > right) r = right; };
    void trimBottom(N2Coord &b) { if(b > bottom) b = bottom; };
};

#endif //N2GEOMETRY_H_2006_11_22
